package com.grupobbva.iici.dao.impl;

import java.io.Serializable;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import oracle.jdbc.internal.OracleTypes;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;

import com.grupobbva.iici.dao.ProcesoDAO;
import com.grupobbva.iici.serializable.Log;
import com.grupobbva.iici.serializable.Scheduler;
import com.grupobbva.iici.util.Conexion;

@Repository("ProcesoDAO")
public class ProcesoDAOImpl  extends BaseDAOImpl implements ProcesoDAO,Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger log = Logger.getLogger(ProcesoDAOImpl.class);


	public List<Scheduler> obtenerScheduler() {
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		List<Scheduler> lstSchedulerDTO = null;
		try {
			lstSchedulerDTO = new ArrayList<Scheduler>();
			con = Conexion.getConnection();
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_OBTENER_SCHEDULERS(?)}");
			stm.registerOutParameter(1, OracleTypes.CURSOR);
			stm.execute();
			rst = (ResultSet) stm.getObject(1);
			while (rst.next()) {
				Scheduler schedulerDTO = new Scheduler();
				schedulerDTO.setIdScheduler(rst.getInt(1));
				schedulerDTO.setIdEstado(rst.getString(2));
				schedulerDTO.setDescripcion(rst.getString(3));
				schedulerDTO.setDia(rst.getString(4));
				schedulerDTO.setHora(rst.getString(5));
				schedulerDTO.setMinuto(rst.getString(6));
				schedulerDTO.setSegundo(rst.getString(7));
				schedulerDTO.setDiaSemana(rst.getString(8));
				schedulerDTO.setFechaProceso(rst.getDate(9));
				schedulerDTO.setNombreArchivo(rst.getString(10));
				Integer diaMes		=rst.getInt(11);
				Integer horaDia		=rst.getInt(12);
				Integer minutoDia	=rst.getInt(13);
				Integer segundoDia	=rst.getInt(14);
				Integer diaSemana	=rst.getInt(15);
				if(validarEjecucion(schedulerDTO,diaMes,horaDia,minutoDia,segundoDia,diaSemana)){
					lstSchedulerDTO.add(schedulerDTO);
				}
			}			
		} catch (Exception e) {
			log.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
		return lstSchedulerDTO;
	}



	private boolean validarEjecucion(Scheduler schedulerDTO, Integer diaMes, Integer horaDia, Integer minutoDia, Integer segundoDia, Integer diaSemana) {
		if("*".equals(schedulerDTO.getDia()) 					|| diaMes==Integer.parseInt(schedulerDTO.getDia())){
			if("*".equals(schedulerDTO.getHora()) 				|| horaDia==Integer.parseInt(schedulerDTO.getHora())){
				if("*".equals(schedulerDTO.getMinuto()) 		|| minutoDia==Integer.parseInt(schedulerDTO.getMinuto())){
					if("*".equals(schedulerDTO.getSegundo()) 	|| segundoDia==Integer.parseInt(schedulerDTO.getSegundo())){
						if("*".equals(schedulerDTO.getDiaSemana()) || diaSemana==Integer.parseInt(schedulerDTO.getDiaSemana())){
							return true;
						}
					}
				}
			}
		}
		return false;
	}



	public Scheduler obtenerScheduler(Scheduler schedulerDTO) {
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		try {
			log.info("Ingreso obtenerScheduler");
			con = Conexion.getConnection();
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_OBTENER_SCHEDULER(?,?,?)}");
			stm.setInt(1, schedulerDTO.getIdScheduler());
			stm.setDate(2, new java.sql.Date(schedulerDTO.getFechaProceso().getTime()));
			stm.registerOutParameter(3, OracleTypes.CURSOR);
			stm.execute();
			rst = (ResultSet) stm.getObject(3);
			while (rst.next()) {
				schedulerDTO.setIdScheduler(rst.getInt(1));
				schedulerDTO.setIdEstado(rst.getString(2));
				schedulerDTO.setDescripcion(rst.getString(3));
				schedulerDTO.setDia(rst.getString(4));
				schedulerDTO.setHora(rst.getString(5));
				schedulerDTO.setMinuto(rst.getString(6));
				schedulerDTO.setSegundo(rst.getString(7));
				schedulerDTO.setDiaSemana(rst.getString(8));
				schedulerDTO.setFechaProceso(rst.getDate(9));
				schedulerDTO.setNombreArchivo(rst.getString(10));
					
			}
			log.info("Fin obtenerScheduler");			
		} catch (Exception e) {
			log.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
		return schedulerDTO;
	}

	public void cargarArchivo(Scheduler schedulerDTO, Long tipoCarga, String usuario, boolean existe) {
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		String fecha = sdf.format(schedulerDTO.getFechaProceso());
		try {
			log.info("Inicio cargarArchivo");
			con = Conexion.getConnection();
			log.info(">IdScheduler			:" + schedulerDTO.getIdScheduler());
			log.info(">tipoCarga			:" + tipoCarga);
			log.info(">usuario				:" + usuario);
			log.info(">existe				:" + existe);
			log.info(">horaCarga			:" + fecha);
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_CARGA_ADMINISTRADOR(?,?,?,?,?)}");
			stm.setLong(1, schedulerDTO.getIdScheduler());
			stm.setLong(2, tipoCarga);
			stm.setString(3, usuario);
			stm.setString(4, fecha);
			stm.setInt(5, existe ? 1 : 0);
			stm.execute();
			log.info("Fin cargarArchivo");
		} catch (Exception e) {
			log.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
	}
	
	public Integer generarRegistroCargaMovimiento(Scheduler schedulerDTO, String usuario, boolean existe){
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		String fecha = sdf.format(schedulerDTO.getFechaProceso());
		Integer salida=null;
		try {
			log.info("Ingreso generarRegistroCargaMovimiento");
			con = Conexion.getConnection();
			log.info(">IdConfigScheduler	:" + schedulerDTO.getIdScheduler());
			log.info(">usuario				:" + usuario);
			log.info(">existe				:" + existe);
			log.info(">horaCarga			:" + fecha);
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_CARGA_MOVIMIENTO_INICIO(?,?,?,?,?)}");
			stm.setLong(1, schedulerDTO.getIdScheduler());
			stm.setString(2, usuario);
			stm.setString(3, fecha);
			stm.setInt(4, existe ? 1 : 0);
			stm.registerOutParameter(5, OracleTypes.NUMBER);
			stm.execute();
			log.info("Fin generarRegistroCargaMovimiento");
			salida = stm.getInt(5);	
		} catch (Exception e) {
			logger.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
		return salida;
	}	
	
	public void terminarRegistroCargaMovimiento(Scheduler schedulerDTO, Integer codigoBitacora,String mensaje,String codigoExito) {
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		try {
			log.info("Ingreso terminarRegistroCargaMovimiento");
			con = Conexion.getConnection();
			log.info(">IdConfigScheduler	:" + schedulerDTO.getIdScheduler());
			log.info(">codigoBitacora			:" + codigoBitacora);
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_CARGA_MOVIMIENTO_FINALIZAR(?,?,?,?)}");
			stm.setLong(1, schedulerDTO.getIdScheduler());
			stm.setLong(2, codigoBitacora);
			stm.setString(3, mensaje);
			stm.setString(4, codigoExito);
			stm.execute();
			log.info("Fin terminarRegistroCargaMovimiento");
		} catch (Exception e) {
			logger.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
	}
	
	public void registrarLog(List<Log> lstLog) {
		Connection con = null;
		CallableStatement stm = null;
		ResultSet rst = null;
		try {
			log.info("Ingreso terminarRegistroCargaMovimiento");
			con = Conexion.getConnection();
			con.setAutoCommit(false);
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_REGISTRAR_LOG(?,?,?,?,?,?,?,?)}");
			Integer codigoBitacora=null;
			for(Log mLog:lstLog){
				log.info("registrando>>>"+mLog.getStr_num_registro());
				codigoBitacora=mLog.getCodigoBitacora();
				stm.setInt(1, codigoBitacora);
				stm.setDate(2, new java.sql.Date(mLog.getStr_fec_consulta().getTime()));
				stm.setString(3, mLog.getCodigoServicio());
				stm.setString(4, mLog.getTrazabilidad());
				stm.setString(5, mLog.getStr_num_registro());
				stm.setString(6,mLog.getAplicativo());
				stm.setString(7,mLog.getHoraInicio());
				stm.setString(8,mLog.getHoraFin());
				stm.execute();
			}
			stm.close();
			stm = con.prepareCall("{call IICI.PK_CARGA_ARCHIVO.SP_ACTUALIZAR_DATOS_REGISTRO(?)}");
			stm.setInt(1, codigoBitacora);
			stm.execute();
			con.commit();
			log.info("Fin terminarRegistroCargaMovimiento");
		} catch (Exception e) {
			logger.info(e);
		} finally {
			Conexion.close(con, stm, rst);
		}
	}
	

}
